"""电影应用序列化器模块

定义了用于序列化和反序列化电影相关数据的类。
"""

from typing import Any

from django.core.files.uploadedfile import InMemoryUploadedFile
from rest_framework import serializers

from .models import Movie


class MovieSerializer(serializers.ModelSerializer):
    """电影序列化器类"""

    class Meta:
        model = Movie  # 关联的模型
        fields = ["id", "title", "genres"]  # 序列化的字段


class PreferencesDetailSerializer(serializers.Serializer):
    """偏好详情序列化器类"""

    genre = serializers.CharField(max_length=100, allow_blank=True, required=False, help_text="电影类型")  # 电影类型字段
    director = serializers.CharField(max_length=100, allow_blank=True, required=False, help_text="导演")  # 导演字段
    actor = serializers.CharField(max_length=100, allow_blank=True, required=False, help_text="演员")  # 演员字段
    year = serializers.IntegerField(
        min_value=1900, max_value=2099, required=False, allow_null=False, help_text="年份"
    )  # 年份字段

    def validate(self, data: dict[str, Any]) -> dict[str, Any]:
        """
        验证偏好详情数据

        Args:
            data: 待验证的数据

        Returns:
            dict: 验证后的数据

        Raises:
            serializers.ValidationError: 当所有字段都为空时抛出异常
        """
        # 检查所有字段是否都为空或未提供
        if all(value in [None, ""] for value in data.values()):
            raise serializers.ValidationError(
                "At least one preference must be provided."
            )
        return data


class AddPreferenceSerializer(serializers.Serializer):
    """添加偏好序列化器类"""

    new_preferences = PreferencesDetailSerializer(help_text="新的偏好设置")  # 新的偏好设置字段


class PreferencesSerializer(serializers.Serializer):
    """偏好序列化器类"""

    genre = serializers.ListField(child=serializers.CharField(), required=False, help_text="电影类型列表")  # 电影类型列表字段
    director = serializers.ListField(child=serializers.CharField(), required=False, help_text="导演列表")  # 导演列表字段
    actor = serializers.ListField(child=serializers.CharField(), required=False, help_text="演员列表")  # 演员列表字段
    year = serializers.ListField(child=serializers.CharField(), required=False, help_text="年份列表")  # 年份列表字段


class AddToWatchHistorySerializer(serializers.Serializer):
    """添加到观看历史序列化器类"""

    id = serializers.IntegerField(help_text="电影ID")  # 电影ID字段

    def validate_id(self, value: int) -> int:
        """
        验证电影ID是否存在

        Args:
            value: 电影ID

        Returns:
            int: 验证后的电影ID

        Raises:
            serializers.ValidationError: 当电影不存在时抛出异常
        """
        try:
            Movie.objects.get(id=value)
        except Movie.DoesNotExist:
            raise serializers.ValidationError("Invalid movie ID. No such movie exists.")
        return value


class WatchHistorySerializer(serializers.Serializer):
    """观看历史序列化器类"""

    title = serializers.CharField(max_length=255, help_text="电影标题")  # 电影标题字段
    year = serializers.IntegerField(help_text="年份")  # 年份字段
    director = serializers.CharField(max_length=255, help_text="导演")  # 导演字段
    genre = serializers.CharField(max_length=255, help_text="电影类型")  # 电影类型字段


class GeneralFileUploadSerializer(serializers.Serializer):
    """通用文件上传序列化器类"""

    file = serializers.FileField(help_text="上传的文件")  # 上传的文件字段

    def validate_file(self, value: InMemoryUploadedFile) -> InMemoryUploadedFile:
        """
        验证上传的文件类型

        Args:
            value: 上传的文件对象

        Returns:
            InMemoryUploadedFile: 验证后的文件对象

        Raises:
            serializers.ValidationError: 当文件类型不支持时抛出异常
        """
        # 验证文件MIME类型
        allowed_types = ["text/csv", "application/json", "application/xml"]
        if value.content_type not in allowed_types:
            raise serializers.ValidationError("Unsupported file type.")

        return value
